package genome;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

//This class holds default values of all parameters for genome configuration. It also reads in a configuration file to setup parameters as required.
public class GenomeParameters extends DefaultHandler{
	/* Table of parameters required by genome package.
	 * BG:
	 * BG_SIZE
	 * BG_MUTATION_RATE
	 * 
	 * CGP:
	 * CGP_NODES
	 * CGP_SIZE
	 * CGP_MUTATION_RATE
	 * CGP_ARITY
	 * CGP_FUNCTION_SET
	 * 
	 * GGT:
	 * GGT_MUTATION_RATE
	 * GGT_SIZE
	 * GGT_MAX_VAL
	 * GGT_MAX_DEPTH
	 * GGT_GRAMMAR
	 * 
	 * IG:
	 * IG_SIZE
	 * IG_MUTATION_RATE
	 * IG_MAX_VAL
	 */
	
	//DEFAULT VALUES
	public static int BG_SIZE = 15;
	public static double BG_MUTATION_RATE = 0.1;
	
	public static int CGP_NODES = 5;
	public static int CGP_ARITY = 2;
	public static int CGP_SIZE = CGP_NODES*(CGP_ARITY+1);
	public static double CGP_MUTATION_RATE = 0.1;
	public static FunctionSet CGP_FUNCTION_SET = new FunctionSet();
	
	public static double GGT_MUTATION_RATE = 0.1;
	public static int GGT_SIZE = 15;
	public static int GGT_MAX_VAL = 4;
	public static int GGT_MAX_DEPTH = 4;
	public static Grammar GGT_GRAMMAR = new NumericalGrammar();
	
	public static int IG_SIZE = 15;
	public static double IG_MUTATION_RATE = 0.1;
	public static int IG_MAX_VAL = 10;
	
	public static String configurationName = "configurations\\config.xml";
	
	public String tempVal;
	
	public GenomeParameters(){
		//use currently loaded configuration
		this(configurationName);
	}

	public GenomeParameters(String s){
		GenomeParameters.configurationName=s;
		parseParameters();
	}
	
	public void parseParameters() {

		//get a factory
		SAXParserFactory spf = SAXParserFactory.newInstance();
		try {

			//get a new instance of parser
			SAXParser sp = spf.newSAXParser();

			//parse the file and also register this class for call backs
			sp.parse(configurationName, this);

		}catch(SAXException se) {
			se.printStackTrace();
		}catch(ParserConfigurationException pce) {
			pce.printStackTrace();
		}catch (IOException ie) {
			ie.printStackTrace();
		}
	}
	
	public void characters(char[] ch, int start, int length) throws SAXException {
		tempVal = new String(ch,start,length);
	}
	
	public void endElement(String uri, String localName, String qName) throws SAXException {

			if (qName.equalsIgnoreCase("BG_SIZE")) {
				GenomeParameters.BG_SIZE = Integer.parseInt(tempVal);
			}
			else if (qName.equalsIgnoreCase("BG_MUTATION_RATE")) {
				GenomeParameters.BG_MUTATION_RATE = Double.parseDouble((tempVal));
				
			}else if (qName.equalsIgnoreCase("CGP_NODES")) {
				GenomeParameters.CGP_NODES = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("CGP_NODES")) {
				GenomeParameters.CGP_ARITY = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("CGP_MUTATION_RATE")) {
				GenomeParameters.CGP_MUTATION_RATE = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("CGP_FUNCTION_SET")) {
				try {
					CGP_FUNCTION_SET = (FunctionSet) (Class.forName(tempVal)).newInstance();
				} catch (ClassNotFoundException e) {
					System.out.println("Could not load function set: class not found");
					e.printStackTrace();
				} catch (InstantiationException e) {
					System.out.println("Could not instantiate class");
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					System.out.println("Could not access class");
					e.printStackTrace();
				}
			}
			
			else if (qName.equalsIgnoreCase("GGT_MUTATION_RATE")) {
				GenomeParameters.GGT_MUTATION_RATE = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("GGT_SIZE")) {
				GenomeParameters.GGT_SIZE = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("GGT_MAX_VAL")) {
				GenomeParameters.GGT_MAX_VAL = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("GGT_GRAMMAR")){
				try {
					GGT_GRAMMAR = (Grammar) (Class.forName(tempVal)).newInstance();
				} catch (ClassNotFoundException e) {
					System.out.println("Could not load function set: class not found");
					e.printStackTrace();
				} catch (InstantiationException e) {
					System.out.println("Could not instantiate class");
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					System.out.println("Could not access class");
					e.printStackTrace();
				}
			}
			
			else if (qName.equalsIgnoreCase("IG_SIZE")) {
				GenomeParameters.IG_SIZE = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("IG_MUTATION_RATE")) {
				GenomeParameters.IG_MUTATION_RATE = Integer.parseInt(tempVal);
			}
			
			else if (qName.equalsIgnoreCase("IG_MAX_VAL")) {
				GenomeParameters.IG_MAX_VAL = Integer.parseInt(tempVal);
			}
	}
	
	public void endDocument(){
		CGP_SIZE = (CGP_ARITY+1)*CGP_NODES;
	}
	
}
